#include "clientmessagemanager.h"

ClientMessageManager::ClientMessageManager(QObject *parent) :
    QObject(parent)
{
    clientConnection = new ClientConnection(this);
    //connections for properly work with ClientConnection and Host
    connect(clientConnection, SIGNAL(signalConnectionSuccessfull()),
            this, SLOT(slotConnectionSuccessfull()));
    connect(clientConnection, SIGNAL(signalConnectionError(QAbstractSocket::SocketError)),
            this, SLOT(slotConnectionError(QAbstractSocket::SocketError)));
    connect(clientConnection, SIGNAL(signalDisconnectedFromSocket()),
            this, SLOT(slotDisconnectedFromSocket()));
    connect(clientConnection, SIGNAL(signalReceived(QString)),
            this, SLOT(slotReceivedCommand(QString)));

}

ClientMessageManager::~ClientMessageManager()
{
    delete clientConnection;
}

void ClientMessageManager::connectToSocket(QString _ip, int _port)
{
    qDebug() << "ClientMessageManager::connectToSocket(QString _ip, int _port)";
    clientConnection->connectToSocket(_ip, _port);
}

void ClientMessageManager::disconnectFromSocket()
{
    if (!connected())
    {
        return;
    }

    clientConnection->disconnectFromSocket();
}

void ClientMessageManager::slotConnectionSuccessfull()
{
    emit signalConnectionSuccessfull();
}

void ClientMessageManager::slotConnectionError(QAbstractSocket::SocketError err)
{
    emit signalConnectionError(err);
}

void ClientMessageManager::slotDisconnectedFromSocket()
{
    emit signalDisconnectedFromSocket();
}

void ClientMessageManager::slotReceivedCommand(QString str)
{
    qDebug() << "ClientMessageManager::slotReceivedCommand("
             << str
             << ")";
    parseToCommand(str);
}

void ClientMessageManager::slotSEND_NICK(QString nickname)
{
    QString str = "CS_SEND_NICK"
            + delimetrs::delim
            + nickname
            + delimetrs::eom;
    clientConnection->sendMessage(str);
}

void ClientMessageManager::slotDISCONNECT()
{
    QString str = "CS_DISCONNECT"
            + delimetrs::eom;
    clientConnection->sendMessage(str);
}

void ClientMessageManager::slotFIRE()
{
    QString str = "CS_FIRE"
            + delimetrs::eom;
    clientConnection->sendMessage(str);
}

void ClientMessageManager::slotMOVE()
{
    QString str = "CS_MOVE"
            + delimetrs::eom;
    clientConnection->sendMessage(str);
}

void ClientMessageManager::slotTURN(char turnDirection)
{
    QString str = "CS_TURN"
            + delimetrs::delim
            + turnDirection
            + delimetrs::eom;
    clientConnection->sendMessage(str);
}

void ClientMessageManager::slotSTOP_MOVE()
{
    QString str = "CS_STOP_MOVE"
            + delimetrs::eom;
    clientConnection->sendMessage(str);
}

void ClientMessageManager::slotSTOP_FIRE()
{
    QString str = "CS_STOP_FIRE"
            + delimetrs::eom;
    clientConnection->sendMessage(str);
}

bool ClientMessageManager::connected()
{
    return clientConnection->connected();
}

void ClientMessageManager::parseToCommand(QString str)
{
    qDebug() << "ClientMessageManager::parseToCommand " << str;
    QString strWithoutEOM = str.left(str.length() - delimetrs::eom.size());
    QStringList listOfElements = strWithoutEOM.split(delimetrs::delim);

    //first position in list - command type
    if (listOfElements.at(0) == "SC_CONN_ACCEPTED")
    {

        emit signalSC_CONN_ACCEPTED(listOfElements.at(1).toInt());
        return;
    }

    if (listOfElements.at(0) == "SC_CONN_REJECTED")
    {
        emit signalSC_CONN_REJECTED(listOfElements.at(1));
        return;
    }
    if (listOfElements.at(0) == "SC_PLAYERLIST")
    {

        QStringList playerList = listOfElements;
        playerList.removeAt(0); //deleting command type
                                //now playerList contains
                                //"1" "nickname1" "2" "nickname2" ...
        emit signalSC_PLAYERLIST(playerList);
        return;
    }
    if (listOfElements.at(0) == "SC_GAME_START")
    {
        emit signalSC_GAME_START();
        return;
    }

    if (listOfElements.at(0) == "SC_GAME_END")
    {
       emit signalSC_GAME_END(listOfElements.at(1).toInt());
       return;
    }

    if (listOfElements.at(0) == "SC_SEND_SNAPSHOT")
    {
        emit signalSC_START_SNAPSHOT();
        int pos = 2;    //position of first playerId in list
                        //first(0) - command type
                        //second(1) - count of players
        for (int i = 0; i < listOfElements.at(1).toInt(); ++i)
        {
            int playerId = listOfElements.at(pos++).toInt();
            int health = listOfElements.at(pos++).toInt();
            int pos_x = listOfElements.at(pos++).toInt();
            int pos_y = listOfElements.at(pos++).toInt();
            char action = listOfElements.at(pos++).at(0).toAscii();
            char direction = listOfElements.at(pos++).at(0).toAscii();
            int progress = listOfElements.at(pos++).toInt();
            emit signalSC_SET_TANK(playerId, health, pos_x, pos_y,
                                   action, direction, progress);
            qDebug() << "ClientMessageManager::parseToCommand snapshot tank"
                     << playerId << health << pos_x << pos_y
                     << action << direction << progress;
        }

        while (1)
        {
            if (listOfElements.count() < pos + 5)                //DANGER
            {
                qDebug() << "ClientMessageManager::parseToCommand snapshot bullet"
                         << "bullets have ended.";
                break;
            }

            int bulletId = listOfElements.at(pos++).toInt();
            int pos_x = listOfElements.at(pos++).toInt();
            int pos_y = listOfElements.at(pos++).toInt();
            char direction = listOfElements.at(pos++).at(0).toAscii();
            int progress = listOfElements.at(pos++).toInt();

            emit signalSC_SET_BULLET(bulletId, pos_x, pos_y,
                                     direction, progress);
            qDebug() << "ClientMessageManager::parseToCommand snapshot bullet"
                     << bulletId << pos_x << pos_y
                     << direction << progress;
        }

        emit signalSC_END_SNAPSHOT();
        return;
    }

    if (listOfElements.at(0) == "SC_SEND_MAP")
    {
        int pos = 1;    //start position of parametrs data
        int size = listOfElements.at(pos++).toInt();
        QString map = listOfElements.at(pos++);
        int health = listOfElements.at(pos++).toInt();
        int motionSpeed = listOfElements.at(pos++).toInt();
        int bulletSpeed = listOfElements.at(pos++).toInt();
        int fireRate = listOfElements.at(pos++).toInt();
        emit signalSC_SEND_MAP(size, size, map, health,
                               motionSpeed, bulletSpeed, fireRate);
        qDebug() << "ClientMessageManager::parseToCommand SC_SEND_MAP map= " << map;
        return;
    }

    if (listOfElements.at(0) == "SC_MOVE")
    {
        emit signalSC_MOVE(listOfElements.at(1).toInt());
        return;
    }

    if (listOfElements.at(0) == "SC_FIRE")
    {
        emit signalSC_FIRE(listOfElements.at(1).toInt());
        return;
    }

    if (listOfElements.at(0) == "SC_TURN")
    {
        emit signalSC_TURN(listOfElements.at(1).toInt(), listOfElements.at(2)[0].toAscii());
        return;
    }

    if (listOfElements.at(0) == "SC_STOP_MOVE")
    {
        emit signalSC_STOP_MOVE(listOfElements.at(1).toInt());
        return;
    }

    if (listOfElements.at(0) == "SC_STOP_FIRE")
    {
        emit signalSC_STOP_FIRE(listOfElements.at(1).toInt());
        return;
    }

    qDebug() << "ClientMessageManager::parseToCommand (message=";

    for (int i = 0; i < listOfElements.count(); ++i)
    {
        qDebug() << listOfElements.at(i);
    }

    emit signalUNKNOWN_COMMAND(str);

}

